package com.ruoyi.worker.service.v2.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.worker.domain.v2.RzAttendanceMonthActualWorkVO;
import com.ruoyi.worker.domain.v2.RzAttendanceSumMonthDetailVO;
import com.ruoyi.worker.domain.v2.RzAttendanceSumMonthVO;
import com.ruoyi.worker.mapper.v2.RzAttendanceSumMonthMapper;
import com.ruoyi.worker.service.v2.RzAttendanceSumMonthService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class RzAttendanceSumMonthServiceImpl implements RzAttendanceSumMonthService {


    @Resource
    private RzAttendanceSumMonthMapper sumMonthMapper;
    @Resource
    private SysDeptMapper sysDeptMapper;

    private Map<String, Map<String, List<Integer>>> actualWorkMap;
    private String currentMonth;

    @Override
    public List<RzAttendanceSumMonthVO> indexDatas(RzAttendanceSumMonthVO params) {
        return sumMonthMapper.sumMonthDatas(params);
    }

    @Override
    public String invalidDatas(RzAttendanceSumMonthVO params) {
        List<RzAttendanceSumMonthVO> results = sumMonthMapper.invalidDates(params);
        StringBuilder sb = new StringBuilder();
        sb.append(params.getMonth());
        sb.append("月");
        sb.append("[");
        for (RzAttendanceSumMonthVO r : results) {
            String date = r.getScheduleDate().split("-")[2];
            sb.append(date);
            sb.append("、");
        }
        return sb.toString().substring(0, sb.length() - 1) + "]号考勤结果未确认，请确认后再查看工资明细！";
    }

    @Override
    public List<RzAttendanceSumMonthDetailVO> details(RzAttendanceSumMonthDetailVO param) {
        if (StringUtils.isEmpty(param.getMonth())) {
            return null;
        }
        Long node1 = System.nanoTime();
        String year = param.getMonth().split("-")[0];
        int month = Integer.parseInt(param.getMonth().split("-")[1]);
        // 开始日期
        String startDate = year + DateUtils.getFirstDayOfMonth(month).substring(4);
        String endDate = year + DateUtils.getLastDayOfMonth(month).substring(4);
        // 基础数据，包含区域、姓名、组别、岗位、身份证、应出勤、旷工、普通迟到、一般迟到、严重迟到、早退
        List<RzAttendanceSumMonthDetailVO> baseDatas = sumMonthMapper.sumMonthDetail(startDate, endDate, param.getDeptId(),
                param.getStaffName(), param.getIdCard(), param.getGroupName(), param.getStationName());
        Long node2 = System.nanoTime();
        // 实际出勤数据
        this.setActualWorkMap(startDate, endDate, param.getDeptId());
        Long node3 = System.nanoTime();
        // 出勤匹配,这步之后补齐实际出勤、通班次数、白班次数、晚班次数
        this.validActualWork(baseDatas);
        Long node4 = System.nanoTime();
//        System.out.println("查询耗时：" + (node2 - node1)); // 5.3s
//        System.out.println("查询耗时：" + (node3 - node2)); // 1.3s
//        System.out.println("算法耗时：" + (node4 - node3)); // 忽略

        return baseDatas;
    }

    @Override
    public Map<String, List<String>> searchOptions(RzAttendanceSumMonthDetailVO param) {
        if (StringUtils.isEmpty(param.getMonth())) {
            return null;
        }
        this.currentMonth = param.getMonth();
        int month = Integer.parseInt(param.getMonth().split("-")[1]);
        // 开始日期
        String year = param.getMonth().split("-")[0];
        String startDate = year + DateUtils.getFirstDayOfMonth(month).substring(4);
        String endDate = year + DateUtils.getLastDayOfMonth(month).substring(4);

        List<String> groupOptions = sysDeptMapper.getGroupOptions4Search(startDate, endDate, param.getDeptId());
        List<String> stationOptions = sysDeptMapper.getStationOptions4Search(startDate, endDate, param.getDeptId());
        return ImmutableMap.of("groups", groupOptions, "stations", stationOptions);
    }

    /**
     * @author: 陈宇寰
     * @date: 2022-01-06 17:05:34
     * @params:
     * @return:
     * @description: 实际出勤、通班次数、白班次数、晚班次数
     */
    private void validActualWork(List<RzAttendanceSumMonthDetailVO> baseDatas) {
        for (RzAttendanceSumMonthDetailVO data : baseDatas) {
            String idCard = data.getIdCard().substring(1);
            String[] attendances = data.getAttendanceGroupName().split(",");
            Map<String, List<Integer>> aw = actualWorkMap.get(idCard);
            if (ObjectUtils.isEmpty(aw)) {
                List<String> ads = Arrays.asList(attendances);
                Collections.replaceAll(ads, "通班", "未出勤");
                Collections.replaceAll(ads, "白班", "未出勤");
                Collections.replaceAll(ads, "晚班", "未出勤");
                data.setAttendances(ads);
//                data.setAttendanceMap(this.setAttendanceWorkMap(data));
            } else {
                List<Integer> idxs = new ArrayList<>();
                for (Map.Entry<String, List<Integer>> m : aw.entrySet()) {
                    String signDate = m.getKey();
                    int idx = DateUtils.getDayIndex(signDate) - 1;
                    if (m.getValue().get(0) == 1 && m.getValue().get(1) == 1) {
                        attendances[idx] = "通班";
                    } else if (m.getValue().get(0) == 1 && m.getValue().get(1) == 2) {
                        attendances[idx] = "白班";
                    } else if (m.getValue().get(0) == 2 && m.getValue().get(1) == 1) {
                        attendances[idx] = "晚班";
                    } else {
                        attendances[idx] = "未出勤";
                    }
                    idxs.add(idx);
                }
                for (int i = 0; i < attendances.length; i++) {
                    if (idxs.contains(i)) {
                        continue;
                    }
                    if (attendances[i].contains("班")) {
                        attendances[i] = "未出勤";
                    }
                }
                data.setAttendances(Arrays.asList(attendances));
//                data.setAttendanceMap(this.setAttendanceWorkMap(data));
            }
            int crossCount = Collections.frequency(data.getAttendances(), "通班");
            int dayCount = Collections.frequency(data.getAttendances(), "白班");
            int nightCount = Collections.frequency(data.getAttendances(), "晚班");
            data.setActualBe(crossCount + dayCount * 0.4 + nightCount * 0.6);
            data.setCrossCount(crossCount);
            data.setDayCount(dayCount);
            data.setNightCount(nightCount);
        }
    }

    private Map<String, String> setAttendanceWorkMap(RzAttendanceSumMonthDetailVO data) {
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < data.getAttendances().size(); i++) {
            String dt = "";
            if (i < 10) {
                dt = StringUtils.format("{}-{}", this.currentMonth, "0" + (i + 1));
            } else {
                dt = StringUtils.format("{}-{}", this.currentMonth, i + 1);
            }
            map.put(dt, data.getAttendances().get(i));
        }
        return map;
    }

    /**
     * @author: 陈宇寰
     * @date: 2022-01-06 17:06:13
     * @params:
     * @return:
     * @description: 实际的出勤结果hash化
     */
    private void setActualWorkMap(String startDate, String endDate, String deptId) {
        List<RzAttendanceMonthActualWorkVO> actualResult = sumMonthMapper.actualWorkResult(startDate, endDate, deptId);
        actualWorkMap = new HashMap<>();
        actualResult.forEach(item -> {
            Map<String, List<Integer>> tempMap = actualWorkMap.get(item.getIdCard());
            if (ObjectUtils.isEmpty(tempMap)) {
                tempMap = new HashMap<>();
            }
            List<Integer> resultList = tempMap.get(item.getWorkDate());
            if (CollectionUtil.isEmpty(resultList)) {
                resultList = new ArrayList<>();
            }
            resultList.add(item.getDayResult());
            resultList.add(item.getNightResult());
            tempMap.put(item.getWorkDate(), resultList);
            actualWorkMap.put(item.getIdCard(), tempMap);
        });
    }
}
